package typejump;

import java.util.LinkedList;

/**
 * This class stores messages to be passed around internally. Objects can stick
 * messages in this message list, and other objects can check for messages and
 * remove them.
 * @author g
 *
 */
public class MessageList {

	private final Object msl = new Object();
	private LinkedList<Message> messages = new LinkedList<Message>();
	
	public String[] getMessages() {
		return (String[])messages.toArray();
	}
	
	/**
	 * Returns true if this list contains the specified message.
	 * @param message
	 * @return
	 */
	public boolean hasMessage(String message) {
		synchronized (msl) {
		message = message.toLowerCase().trim();
		for (Message s : messages) {
			if (s.equals(message))
				return true;
		}
		return false;
		}
	}
	
	/**
	 * Consumes this message, if it exists.
	 * @param message
	 * @return true if this message was in the list, false otherwise.
	 */
	public boolean consumeMessage(String message) {
		synchronized (msl) {
		message = message.toLowerCase().trim();
		Message tom = null;
		for (Message m : messages) {
			if (m.equals(message)) {
				tom = m;
				break;
			}
		}
		if (tom == null) return false;
		messages.remove(tom);
		return true;
		}
	}
	
	/**
	 * Adds this message to the list. Duplicates are allowed.
	 * @param message
	 */
	public void addMessage(String message) {
		synchronized (msl) {
		messages.add(new Message(message));
		}
	}
	
	/**
	 * Adds this message to the list. It will be deleted after a full frame passes.
	 * @param message
	 */
	public void addBriefMessage(String message) {
		synchronized (msl) {
		messages.add(new Message(message, 1));
		}
	}
	
	/**
	 * Returns the number of messages in this list.
	 * @return
	 */
	public int messageCount() {
		synchronized (msl) {
		return messages.size();
		}
	}

	private LinkedList<Message> toRemove = new LinkedList<Message>();
	public synchronized void tick() {
		synchronized (msl) {
		toRemove.clear();
		for (Message m : messages) {
			if (m.tick())
				toRemove.add(m);
		}
		for (Message m : toRemove)
			messages.remove(m);
		}
	}
}

class Message {
	private String message;
	private int life;
	private boolean immortal;
	public Message(String message, int life) {
		this.message = message.toLowerCase().trim();
		this.life = life;
		this.immortal = false;
	}
	public Message(String message) {
		this.message = message.toLowerCase().trim();
		this.life = 0;
		this.immortal = true;
	}
	
	public boolean tick() {
		if (immortal) return false;
		return (life--) < 0;
	}
	
	@Override
	public String toString() {
		return message;
	}
	
	@Override
	public boolean equals(Object other) {
		return other.toString().equals(message);
	}
	
	@Override
	public int hashCode() {
		return message.hashCode();
	}
}
